#ifndef POINT_3F_H
#define POINT_3F_H

#pragma once

#include <LDF/LargeDisplayFrameworkLayer.h>

/**
 * This class represents a 3D point with double values.
 *
 * @author Fabricio Anastacio - fabriciocfa@yahoo.com
 * @since June 26, 2007
 */
class LARGEDISPLAYFRAMEWORKLAYER_API Point3d
{
	// Attributes
public:
	/** The x-coordinate of this point. */
	double x;
	/** The y-coordinate of this point. */
	double y;
	/** The z-coordinate of this point. */
	double z;

	// Methods
public:

	/**
	 * Constructs a 3D point with double values as given by the arguments.
	 *
	 * @param ax the x-coordinate value.
	 * @param ay the y-coordinate value.
	 * @param az the z-coordinate value.
	 */
	Point3d(double ax = 0.0, double ay = 0.0, double az = 0.0);
	/**
	 * Destroys this point object.
	 */
	~Point3d(void);

	/**
	 * Assignment operator.
	 *
	 * @param p the Point3d object whose values will be assigned to this one.
	 */
	Point3d& operator=(const Point3d& p) {
		x = p.x;
		y = p.y;
		z = p.z;
		return *this;
	}


	/**
	 * Converts the contents of this point into an array of 3 doubles.
	 *
	 * @param arrayPoint the array of 3 doubles where the contents of this point
	 * will be placed.
	 */
	inline void convertToArray(double* arrayPoint) {
		arrayPoint[0] = x; arrayPoint[1] = y; arrayPoint[2] = z;
	};



	// ARITHMETICAL OPERATORS
	/**
	 * Adds the vector v to the current vector.
	 *
	 * @param v the vector to be added to this one.
	 */
	inline Point3d& operator+=(const Point3d& v) {
		x += v.x;
		y += v.y;
		z += v.z;
		return *this;
	};
	/**
	 * Subtracts the vector v to the current vector.
	 *
	 * @param v the vector to be subtracted from this one.
	 */
	inline Point3d& operator-=(const Point3d& v) {
		x -= v.x;
		y -= v.y;
		z -= v.z;
		return *this;
	};
	/**
	 * Multiplies the value of the scalar s by the current vector.
	 *
	 * @param s the scalar value to be multipled by this vector.
	 */
	inline Point3d& operator*=(const double s) {
		x *= s;
		y *= s;
		z *= s;
		return *this;
	};
	/**
	 * Divides the value of the scalar s by the current vector.
	 *
	 * @param s the scalar value to be divided by this vector.
	 */
	inline Point3d& operator/=(const double s) {
		x /= s;
		y /= s;
		z /= s;
		return *this;
	};
	
	/**
	 * Returns the result of adding the vector v to the current vector.
	 *
	 * @param v the vector to be added to this one.
	 * @return the resulting of adding this vector to v.
	 */
	inline Point3d operator+(const Point3d& v) const {
		Point3d r = *this;
		r += v;
		return r;
	};
	/**
	 * Returns the result of subtracting the vector v from the current vector.
	 *
	 * @param v the vector to be added to this one.
	 * @return the result of subtracting this vector from v.
	 */
	inline Point3d operator-(const Point3d& v) const {
		Point3d r = *this;
		r -= v;
		return r;
	};
	/**
	 * Returns the result of multiplying this vector by the scalar s.
	 *
	 * @param s the scalar value to be multiplied by this vector.
	 * @return the result of multiplying this vector by s.
	 */
	inline Point3d operator*(const double s) const {
		Point3d r = *this;
		r *= s;
		return r;
	};
	/**
	 * Returns the result of dividing this vector by the scalar s.
	 *
	 * @param s the scalar value to be divided by this vector.
	 * @return the result of dividing this vector by s.
	 */
	inline Point3d operator/(const double s) const {
		Point3d r = *this;
		r /= s;
		return r;
	};



	// DEBUGGING
	/**
	 * Prints this point on the console for debugging purposes.
	 */
	void print();
};

#endif // POINT_3F_H

